package elasticsearch

import (
	"context"
	"github.com/olivere/elastic/v7"
	"runtime"
	"strings"
	"time"

	log "github.com/sirupsen/logrus"
)

var ESServerURL []string

// ESClient for elasticsearch connection
var ESClient *elastic.Client

// CanUseESClient for if elasticsearch connection can be used or not. 1 for can't
var CanUseESClient int = 0

//Err for connection err
var Err error

var logger *log.Entry

// HealthyCheckStop for elasticsearch connection healty check routine control
var HealthyCheckStop = make(chan struct{}, 1)

// RebuildConnectionStop for elasticsearch connection rebuild routine control
var RebuildConnectionStop = make(chan struct{}, 1)

func BuildConnection() {
	ESClient, Err = elastic.NewClient(
		elastic.SetSniff(false),
		elastic.SetURL(ESServerURL...))
	//elastic.SetURL(config.ESurls...))
	if Err != nil {
		logger.Errorf("Failed to build elasticsearch connection")
		//logger.Errorf("Failed to build elasticsearch connection: %s %s", strings.Join(typev1elasticsearch.ESServerURL, ","), Err.Error())
		CanUseESClient = 1
	}
	go healthyCheck()
	go rebuildConnection()
}

//func init() {
//	logger = log.WithFields(log.Fields{
//		"traffic-analysis": "elasticsearch-connection",
//	})
//	buildConnection()
//
//	go healthyCheck()
//	go rebuildConnection()
//}

func healthyCheck() {
	ping := ESClient.Ping(strings.Join(ESServerURL, ","))
	for {
		select {
		case <-HealthyCheckStop:
			goto exit
		default:
			if CanUseESClient != 1 {
				_, _, Err = ping.Do(context.Background())
				if Err != nil {
					logger.Errorf("Failed to build elasticsearch connection: %s %s", strings.Join(ESServerURL, ","), Err.Error())
					CanUseESClient = 1
				} else {
					CanUseESClient = 0
				}
			}

			time.Sleep(5 * time.Second)

		}

	}
exit:
}

func rebuildConnection() {
	for {
		select {
		case <-RebuildConnectionStop:
			goto exit
		default:
			if CanUseESClient == 1 {
				BuildConnection()
			}
			time.Sleep(5 * time.Second)
		}

	}
exit:
}

func CheckClient() {
	err := recover()
	if err != nil {
		switch err.(type) {
		case runtime.Error:
			log.Errorf("Runtime error")
		default:
			log.Errorf("ES Error")
		}
	}
}
